<template>
  <div class="CDynamicForm" v-if="modelValue?.template">
    <n-form :inline="width > 800" ref="formRef">
      <template v-for="item in modelValue!.template">
        <slot v-if="$slots[item.prop]" :name="item.prop" :data="item"></slot>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'input'" :label="item.label" :path="item.prop">
          <n-input :disabled="item.disabled" v-model:value="item.value" :placeholder="'请输入' + item.label" />
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'number'" :label="item.label" :path="item.prop">
          <n-input-number :disabled="item.disabled" v-model:value="item.value" :placeholder="'请输入' + item.label" />
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'select'" :label="item.label" :path="item.prop">
          <n-select :disabled="item.disabled" v-model:value="item.value"
            :options="(item.options?.every(e => typeof e === 'string')) ? item.options!.map(e => ({ label: e, value: e })) : item.options"
            :placeholder="'请选择' + item.label">
          </n-select>
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'switch'" :label="item.label" :path="item.prop">
          <n-switch :disabled="item.disabled" v-model:value="item.value" />
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'image'" :label="item.label" :path="item.prop">
          <c-upload-image v-model:file-list="item.value" :max="item.max"></c-upload-image>
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'slider'" :label="item.label" :path="item.prop">
          <n-slider :disabled="item.disabled" :min="item.min" :step="item.step" v-model:value="item.value"
            :max="item.max" />
          <n-input-number :disabled="item.disabled" :min="item.min" :step="item.step" v-model:value="item.value"
            :max="item.max" size="small" />
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'json'" :label="item.label" :path="item.prop">
          <c-upload-json v-model:file-list="item.value" :max="item.max"></c-upload-json>
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'folderPathInput'" :label="item.label"
          :path="item.prop">
          <CSelectFolder :prop="item.prop" :disabled="item.disabled!" v-model="item.value" :filters="item.filters!"
            :defaultPath="item.defaultPath!" :label="item.label" />
        </n-form-item>
        <n-form-item :rule="createRule(item)" v-else-if="item.type === 'filePathInput'" :label="item.label"
          :path="item.prop">
          <n-input :disabled="item.disabled" v-model:value="item.value" :placeholder="'请输入' + item.label" />
          <c-button :disabled="item.disabled" v-if="TauriF.isTauri()" @click="selectFile(item)" iconName="FolderRound"
            quaternary type='primary'></c-button>
        </n-form-item>
        <n-form-item v-else-if="item.type === 'preForm'" :label="item.label" :path="item.prop">
          <n-select key="key" @update:value="preTemplateChange($event)"
            :options="Object.keys(modelValue!.backups).map(key => ({ label: key, key, value: key }))" placeholder="请选择预设"
            :props="item" v-model:value="item.value">
            <template #action>
              <n-space>
                <c-input v-model:value="preTemplateName" placeholder="请输入新预设的名称"></c-input>
                <n-button :disabled="!preTemplateName" @click="addPreTemplate(item)" dashed type='primary'>
                  确认新增
                </n-button>
                <n-button @click="deletePreTemplate(item.value, item)" dashed type='error'>
                  删除当前选中预设
                </n-button>
              </n-space>
            </template>
          </n-select>
        </n-form-item>
      </template>
    </n-form>
  </div>
</template>

<script setup lang='ts'>
const modelValue = defineModel<FormTemplatesOption>('value')
const TauriF = Tauri
const preTemplateName = ref<string>('')
const addPreTemplate = (data: FormTemplate) => {
  data.value = preTemplateName.value
  modelValue.value!.backups![data.value] = JSON.stringify(modelValue.value!.template)
}
const deletePreTemplate = async (key: string, data: FormTemplate) => {
  delete modelValue.value!.backups![key]
  await nextTick()
  data.value = null
}
const preTemplateChange = (value: string) => {
  modelValue.value!.template = JSON.parse(modelValue.value!.backups![value])
}
const selectFile = async (item: any) => {
  const { defaultPath, filters } = item
  const path = await Tauri.dialogOpen({
    title: '选择文件',
    defaultPath,
    filters,
    multiple: false,
  })
  if(path){
    item.value = path
  }
}
const createRule = (item: FormTemplate) => {
  if (item.required) {
    return {
      required: true,
      validator: () => {
        if (item.value === undefined || item.value === null || item.value === '') {
          return new Error('请输入' + item.label)
        } else {
          return true
        }
      }, message: '请输入' + item.label, trigger: ['input', 'blur']
    }
  }
}
const { width } = useWindowSize() 
</script>

<style lang='scss'>
.n-form-item-blank {
  gap: 10px;
}
</style>